{
 "cells": [
  {
   "cell_type": "raw",
   "id": "df7d42b9-58a6-434c-a2d7-0b61142f6d3e",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_position: 6\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2195672-0cab-4967-ba8a-c6544635547d",
   "metadata": {},
   "source": [
    "# Construct Filters\n",
    "\n",
    "We may want to do query analysis to extract filters to pass into retrievers. One way we ask the LLM to represent these filters is as a Zod schema. There is then the issue of converting that Zod schema into a filter that can be passed into a retriever. \n",
    "\n",
    "This can be done manually, but LangChain also provides some \"Translators\" that are able to translate from a common syntax into filters specific to each retriever. Here, we will cover how to use those translators."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc1302ff",
   "metadata": {},
   "source": [
    "## Setup\n",
    "#### Install dependencies\n",
    "\n",
    "```{=mdx}\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<Npm2Yarn>\n",
    "  langchain zod\n",
    "</Npm2Yarn>\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70cd3b6d",
   "metadata": {},
   "source": [
    "\n",
    "In this example, `year` and `author` are both attributes to filter on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "64055006",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { z } from \"zod\";\n",
    "\n",
    "const searchSchema = z.object({\n",
    "  query: z.string(),\n",
    "  startYear: z.number().optional(),\n",
    "  author: z.string().optional(),\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "44eb6d98",
   "metadata": {},
   "outputs": [],
   "source": [
    "const searchQuery: z.infer<typeof searchSchema> = {\n",
    "  query: \"RAG\",\n",
    "  startYear: 2022,\n",
    "  author: \"LangChain\"\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e8ba6705",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { Comparison, Comparator } from \"langchain/chains/query_constructor/ir\";\n",
    "\n",
    "function constructComparisons(query: z.infer<typeof searchSchema>): Comparison[] {\n",
    "    const comparisons: Comparison[] = [];\n",
    "    if (query.startYear !== undefined) {\n",
    "      comparisons.push(\n",
    "        new Comparison(\n",
    "          \"gt\" as Comparator,\n",
    "          \"start_year\",\n",
    "          query.startYear,\n",
    "        )\n",
    "      );\n",
    "    }\n",
    "    if (query.author !== undefined) {\n",
    "      comparisons.push(\n",
    "        new Comparison(\n",
    "          \"eq\" as Comparator,\n",
    "          \"author\",\n",
    "          query.author,\n",
    "        )\n",
    "      );\n",
    "    }\n",
    "    return comparisons;\n",
    "  }\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6a79c9da",
   "metadata": {},
   "outputs": [],
   "source": [
    "const comparisons = constructComparisons(searchQuery);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2d0e9689",
   "metadata": {},
   "outputs": [],
   "source": [
    "import {\n",
    "  Operation,\n",
    "  Operator,\n",
    "} from \"langchain/chains/query_constructor/ir\";\n",
    "\n",
    "const _filter = new Operation(\"and\" as Operator, comparisons)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d75455ae",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{\n",
       "  \u001b[32m\"$and\"\u001b[39m: [\n",
       "    { start_year: { \u001b[32m\"$gt\"\u001b[39m: \u001b[33m2022\u001b[39m } },\n",
       "    { author: { \u001b[32m\"$eq\"\u001b[39m: \u001b[32m\"LangChain\"\u001b[39m } }\n",
       "  ]\n",
       "}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { ChromaTranslator } from \"langchain/retrievers/self_query/chroma\";\n",
    "\n",
    "new ChromaTranslator().visitOperation(_filter)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
